package com.xuyiwei.xblog.business.article.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.xuyiwei.xblog.business.article.dao.CommentMapper;
import com.xuyiwei.xblog.business.article.model.Comment;
import com.xuyiwei.xblog.business.article.result.article.input.CommentConditionVO;
import com.xuyiwei.xblog.business.article.result.article.out.CommentDto;
import com.xuyiwei.xblog.business.article.service.ICommentService;
import com.xuyiwei.xblog.business.system.model.Config;
import com.xuyiwei.xblog.business.system.service.IConfigService;
import com.xuyiwei.xblog.business.system.service.IMailService;
import com.xuyiwei.xblog.core.base.constant.enums.CommentStatusEnum;
import com.xuyiwei.xblog.core.base.constant.enums.TemplateKeyEnum;
import com.xuyiwei.xblog.core.common.constant.factory.ConstantFactory;
import com.xuyiwei.xblog.core.exception.GunsException;
import com.xuyiwei.xblog.core.shiro.ShiroKit;
import com.xuyiwei.xblog.core.shiro.ShiroUser;
import com.xuyiwei.xblog.core.support.HttpKit;
import com.xuyiwei.xblog.core.util.*;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import eu.bitwalker.useragentutils.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * <p>
 * 文章评论 服务实现类
 * </p>
 *
 * @author xuyiwei
 * @since 2018-10-29
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {

    private static Logger logger = LoggerFactory.getLogger(CommentServiceImpl.class);

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private IConfigService configService;

    @Autowired
    private IMailService mailService;

    @Value("${baidu.apiAk}")
    private String baiduApiAk;

    @Override
    public List<CommentDto> findPageByCondition(Page<CommentDto> page, CommentConditionVO vo, String orderField, boolean isAsc) {
        List<CommentDto> list = commentMapper.findPageByCondition(page, vo, orderField, isAsc);
        for (CommentDto dto : list) {
            ConstantFactory.me().getCommentPage(dto);
        }
        return list;
    }

    @Override
    @Transactional(readOnly = false)
    public void reply(Comment comment) {
        Config config = configService.get();
        ShiroUser user = ShiroKit.getUser();
        comment.setQq(user.getQq());
        comment.setEmail(user.getEmail());
        comment.setNickname(user.getNickName());
        comment.setAvatar( user.getAvatar());
        comment.setUrl(config.getSiteUrl());
        comment.setUserId(user.getId());
        comment.setStatus(CommentStatusEnum.APPROVED.toString());
        comment.setPid(comment.getId());
        comment.setId(null);
        this.fullComment(comment);
        this.insert(comment);
        this.sendEmail(comment);
    }

    public void sendEmail(Comment comment) {
        // 发送邮件通知，此处如发生异常不应阻塞当前的业务流程
        // 可以进行日志记录等操作
        if (null != comment.getPid() && 0 != comment.getPid()) {
            // 给被评论的用户发送通知
            Comment commentDB = commentMapper.selectById(comment.getPid());
            mailService.send(commentDB, TemplateKeyEnum.TM_COMMENT_REPLY, false);
        } else {
            mailService.sendToAdmin(comment);
        }

    }

    @Override
    public void commentForAdmin(Comment comment) {
        Config config = configService.get();
        ShiroUser user = ShiroKit.getUser();
        comment.setQq(user.getQq());
        comment.setEmail(user.getEmail());
        comment.setNickname(user.getNickName());
        comment.setAvatar( user.getAvatar());
        comment.setUrl(config.getSiteUrl());
        comment.setUserId(user.getId());
        comment.setStatus(CommentStatusEnum.APPROVED.toString());
        comment.setPid(comment.getId());
        comment.setId(null);
        this.fullComment(comment);
        this.insert(comment);
    }

    @Override
    public void comment(Comment comment) {
        fullComment(comment);
        this.insert(comment);
        this.sendEmail(comment);
    }


    @Override
    public Comment fullComment(Comment comment) {
        if (StringUtils.isEmpty(comment.getNickname())) {
            throw new GunsException("500", "必须输入昵称哦~~");
        }
        String content = comment.getContent();
        if (!XssKillerUtil.isValid(content)) {
            throw new GunsException("500", "内容不合法，请不要使用特殊标签哦~~");
        }
        content = XssKillerUtil.clean(content.trim()).replaceAll("(<p><br></p>)|(<p></p>)", "");
        if (StringUtils.isEmpty(content) || "\n".equals(content)) {
            throw new GunsException("500", "不说话可不行，必须说点什么哦~~");
        }
        // 过滤非法属性和无用的空标签
        comment.setContent(content);
        comment.setNickname(HtmlUtil.html2Text(comment.getNickname()));
        comment.setQq(HtmlUtil.html2Text(comment.getQq()));
        comment.setAvatar(HtmlUtil.html2Text(comment.getAvatar()));
        comment.setEmail(HtmlUtil.html2Text(comment.getEmail()));
        comment.setUrl(HtmlUtil.html2Text(comment.getUrl()));
        HttpServletRequest request = HttpKit.getRequest();
        String ua = request.getHeader("User-Agent");
        UserAgent agent = UserAgent.parseUserAgentString(ua);
        // 浏览器
        Browser browser = agent.getBrowser();
        String browserInfo = browser.getName();
//        comment.setBrowserShortName(browser.getShortName());// 此处需开发者自己处理
        // 浏览器版本
        Version version = agent.getBrowserVersion();
        if (version != null) {
            browserInfo += " " + version.getVersion();
        }
        comment.setBrowser(browserInfo);
        // 操作系统
        OperatingSystem os = agent.getOperatingSystem();
        comment.setOs(os.getName());
//        comment.setOsShortName(os.getShortName());// 此处需开发者自己处理
        comment.setIp(IpUtil.getRealIp(request));
        String address = "定位失败";
        try {
            String locationJson = RestClientUtil.get(UrlBuildUtil.getLocationByIp(comment.getIp(), baiduApiAk));
            JSONObject localtionContent = JSONObject.parseObject(locationJson).getJSONObject("content");
            // 地址详情
            JSONObject addressDetail = localtionContent.getJSONObject("address_detail");
            // 省
            String province = addressDetail.getString("province");
            // 市
            String city = addressDetail.getString("city");
            // 区
            String district = addressDetail.getString("district");
            // 街道
            String street = addressDetail.getString("street");
            // 街道编号
//            String street_number = addressDetail.getString("street_number");
            StringBuffer sb = new StringBuffer(province);
            if (!StringUtils.isEmpty(city)) {
                sb.append(city);
            }
            if (!StringUtils.isEmpty(district)) {
                sb.append(district);
            }
            if (!StringUtils.isEmpty(street)) {
                sb.append(street);
            }
            address = sb.toString();
            // 经纬度
            JSONObject point = localtionContent.getJSONObject("point");
            // 纬度
            String lat = point.getString("y");
            // 经度
            String lng = point.getString("x");
            comment.setLat(lat);
            comment.setLng(lng);
            comment.setAddress(address);
        } catch (Exception e) {
            comment.setAddress("未知");
            logger.error("获取地址失败");
        }
        if (StringUtils.isEmpty(comment.getStatus())) {
            comment.setStatus(CommentStatusEnum.VERIFYING.toString());
        }
        return comment;
    }

}
